Controlled and Uncontrolled Patterns are two approaches to managing component data and user input in React. Controlled components receive their important values through props, usually React state, while uncontrolled components manage certain values internally or through the DOM.
These patterns are commonly used in forms, text inputs, checkboxes, dropdowns, search fields, and reusable UI components.
A controlled component is a component whose important value is controlled by its parent through props. For form fields, React state typically stores the current value, and an event handler updates that state when the user interacts with the field.
Whenever the state changes, React renders the input with the updated value.
Example: Controlled Input
import { useState } from "react";
function ControlledInput() {
const [name, setName] = useState("");
return (
<div>
<label htmlFor="name">Enter your name:</label>
<input
id="name"
type="text"
value={name}
onChange={(event) => setName(event.target.value)}
/>
<p>Your name is: {name}</p>
</div>
);
}
export default ControlledInput;
How It Works
useState("") creates a state variable to store the input value.
value={name} makes the input's displayed value follow React state.
onChange handles changes made by the user.
setName(event.target.value) updates the state immediately.
The paragraph displays the current name as the user types.
Important: A controlled text input should receive a string value throughout its lifetime. Use an empty string as the initial value if no text has been entered yet.
2. What Are Uncontrolled Components?
An uncontrolled component manages its current form value primarily through the DOM rather than having React state dictate the value on every render. React can provide an initial value using defaultValue or an initial checkbox state using defaultChecked.
You can read the current value when needed, commonly through a React ref or the submitted form data.
Example: Uncontrolled Input Using useRef
import { useRef } from "react";
function UncontrolledInput() {
const nameRef = useRef(null);
function handleSubmit(event) {
event.preventDefault();
alert("Your name is: " + nameRef.current.value);
}
return (
<form onSubmit={handleSubmit}>
<label htmlFor="name">Enter your name:</label>
<input
id="name"
type="text"
ref={nameRef}
defaultValue=""
/>
<button type="submit">Submit</button>
</form>
);
}
export default UncontrolledInput;
How It Works
useRef(null) creates a ref to access the input DOM element.
ref={nameRef} connects the ref to the input.
defaultValue sets the initial input value.
nameRef.current.value reads the current value when the form is submitted.
The input can change without React state being updated on every keystroke.
3. Controlled vs. Uncontrolled Components
Feature
Controlled
Uncontrolled
Value management
Driven by props, commonly backed by React state.
Current form value is primarily managed by the DOM.
Common props
value or checked
defaultValue or defaultChecked
Change handling
Usually uses onChange to update state.
Can read the value through a ref or form submission.
Access to current value
Available directly from state.
Read from the DOM or submitted form data.
Validation while typing
Easy to implement using state.
Requires reading the DOM value or adding event handlers.
Programmatic updates
Update the state that controls the value.
Usually require DOM access or another form-handling approach.
Code complexity
Often requires more state and event-handling code.
Can be simpler for basic forms.
Best use cases
Dynamic forms, live validation, conditional UI.
Simple forms, basic data collection, file inputs.
4. Controlled Text Input
In a controlled text input, React state determines the current text. The onChange handler synchronously updates the state to match the user's input.
Controlled forms are useful when the interface needs to react to changes immediately. Uncontrolled forms can be suitable when the application only needs the entered values at submission time.
Security note: These examples demonstrate input handling only. Real login systems must send credentials securely to a trusted authentication service. Do not log passwords or other sensitive information in production.
13. What Is the Difference Between value and defaultValue?
Prop
Meaning
Pattern
value
Specifies the current value of a text input, textarea, or select.
Controlled
defaultValue
Specifies the initial value of a form field.
Uncontrolled
checked
Specifies the current selected state of a checkbox or radio input.
Controlled
defaultChecked
Specifies the initial selected state of a checkbox or radio input.
Uncontrolled
For a controlled field, the value should be updated through the associated state. For an uncontrolled field, changing defaultValue after the initial render does not act as a command to update its current value.
14. What Is the Role of useState and useRef?
Hook
Purpose
Typical Use
useState
Stores data that affects the rendered UI and triggers a render when updated.
Controlled inputs, live validation, conditional messages.
useRef
Stores a persistent reference without triggering a render when its value changes.
Accessing an input DOM element, focusing an input, reading uncontrolled values.
A ref can also store values unrelated to the DOM, so it is not limited to uncontrolled inputs. Choose the hook based on whether changes need to update the UI.
15. File Inputs in React
An is normally uncontrolled because the browser controls the selected file value. Use a ref to access the selected file objects.
This example checks the email format for demonstration purposes. Production applications should combine appropriate client-side validation with server-side validation.
17. Common Mistakes and Solutions
Mistake
Why It Happens
Solution
Using value without onChange.
The field is controlled but its state cannot be updated by normal user input.
Add an onChange handler or use readOnly if appropriate.
Using value={undefined} initially.
The input may switch from uncontrolled to controlled.
Initialize text state with "" or use value={value ?? ""}.
Using value on a checkbox to control selection.
Checkbox selection is controlled through the checked state.
Use checked and event.target.checked.
Expecting defaultValue to update the current value.
It specifies the initial value rather than continuously controlling the field.
Use a controlled input when programmatic updates are required.
Reading a ref before it is attached.
The DOM element may not yet exist.
Read the ref in an event handler after the component mounts.
Updating controlled state asynchronously on every keystroke.
The rendered value can lag behind the browser input.
Update the state synchronously from the change event.
Using React state for every simple field without a need.
It can add unnecessary state and handlers.
Consider uncontrolled fields when only the submitted value is needed.
18. Best Practices
Use controlled components when you need live validation, conditional rendering, or programmatic updates.
Use uncontrolled components when simple DOM-managed input is sufficient.
Do not switch a field between controlled and uncontrolled modes during its lifetime.
Use strings for controlled text values and booleans for controlled checkbox states.
Use event.target.checked for checkbox and radio selection state.
Use refs for DOM access, focus management, and reading uncontrolled fields.
Give form fields meaningful labels and names.
Use appropriate input types and built-in HTML validation where useful.
Keep sensitive information out of console logs.
Validate important data on the server, even if client-side validation is present.
Choose the simplest pattern that meets the application's requirements.
19. Practical Project: Student Registration Form
Create a Student Registration Form that uses both controlled and uncontrolled patterns.
Requirements
Create controlled fields for student name, email, and course selection.
Create an uncontrolled field for an optional message.
Use a controlled checkbox for accepting terms and conditions.
Compare form submission and validation strategies.
Practice combining controlled and uncontrolled fields in one form.
20. Interview Questions and Answers
Q1. What is a controlled component in React?
A controlled component receives its important value through props, commonly from React state, and uses event handlers to update that state.
Q2. What is an uncontrolled component?
An uncontrolled component keeps its current form value primarily in the DOM rather than having React state control it on every render.
Q3. What is the difference between value and defaultValue?
value controls the current value of a form field, whereas defaultValue specifies its initial value.
Q4. Why is useState used with controlled inputs?
useState stores the current value so the application can update the UI, validate input, and respond to user changes.
Q5. Why is useRef used with uncontrolled inputs?
useRef provides access to the DOM element, allowing the current value to be read when required.
Q6. Which approach is better for forms?
Neither approach is always best. Controlled inputs are useful for dynamic behavior and live validation; uncontrolled inputs can be simpler for basic forms.
Q7. Can controlled and uncontrolled fields be used in the same form?
Yes. A form can use both approaches, as long as each individual field consistently follows one approach.
Q8. How do you control a checkbox?
Use the checked prop and update state using event.target.checked.
Q9. Why should a controlled input not start with undefined?
A controlled text input should receive a string consistently. Starting with undefined and later supplying a string can cause an uncontrolled-to-controlled warning.
Q10. Are file inputs controlled in React?
File inputs are normally uncontrolled because the browser manages file selection. Use a ref to access the selected files.
Q11. Does useRef cause a re-render when its value changes?
No. Updating a ref does not trigger a React render.
Q12. What is live validation?
Live validation checks input while the user types or interacts with a field. Controlled components make it convenient because the current value is already in React state.
21. Practice Exercises
Create a controlled username input that displays the current value.
Create an uncontrolled search form that reads the query using a ref.
Build a controlled checkbox for accepting terms and conditions.
Create a controlled dropdown with five course options.
Build a feedback form with a controlled textarea and character counter.
Create a file upload form that reads the selected filename through a ref.
Build a registration form that combines controlled and uncontrolled fields.
Add validation and test the form's success and error states.
22. Quick Revision
Controlled: The current value is driven by props, commonly React state.
Uncontrolled: The current form value is primarily managed by the DOM.
value and checked are used to control current values.
defaultValue and defaultChecked specify initial values.
useState is useful when changes should update the rendered UI.
useRef is useful for accessing DOM elements and reading uncontrolled fields.
Controlled and uncontrolled patterns are important concepts for handling forms and user input in React. Controlled components provide greater control over input values and make live validation and dynamic UI updates easier. Uncontrolled components let the DOM manage current values and can simplify forms that only need data at submission time.
Understanding both patterns helps you select the right approach for each form field and build maintainable React applications.